 using System;
using System.Collections.Generic;
using System.Text;
using dAmn;
using llAma.Backend.Interface;
using llAma;

namespace llamaServer
{
    public partial class Connection
    {
        string[] acceptedProtocols = { "0.3", "0.2" };
        protected string mUserAgent = "";
        IUserData mCurrentUser = null;
        public IUserData CurrentUser
        {
            get { return mCurrentUser; }
        }
        public string UserAgent
        {
            get { return mUserAgent; }
        }
        string mClientVersion = "";
        public string ClientProtocolVersion
        {
            get { return mClientVersion; }
        }
        [PacketHandler("debug")]
        protected void handleDebug(Packet p, IConnection sender)
        {
            Backend.Implementation.HandlePacket(p, sender);
        }
        [PacketHandler("dAmnClient")]
        [PacketHandler("chatclient")]
        private void packetHandshakeHandler(Packet p, IConnection conn)
        {
            //Its safe to assume state is sane, because this packet will be rejected in all states except for 
            //WAITINGFORHANDSHAKE

            //First, ensure we have a valid version number.
            bool valid = false;
            if (string.IsNullOrEmpty(p.param))
            {
                Disconnect("Invalid Handshake"); return;
            }
            foreach (string s in acceptedProtocols)
                valid = valid || s == p.param;
            if (!valid)
            {
                Disconnect("Protocol version mismatch"); return;
            }
            if (!p.args.ContainsKey("agent"))
            {
                Disconnect("No agent specified"); return;
            }
            //Since it does contain an agent, Log it.
            //Ignore any others, but don't outright reject them.
            mUserAgent = p.args["agent"];
            //At this point, Handshake is good, store the client version.
            mClientVersion = p.param;
            //Now we need to send our part of the handshake.
            Packet toClient = Packet.EmptyPacket;
            if (p.cmd == "chatclient") { toClient.cmd = "chatserver"; mCompatibilityMode = false; }
            else { toClient.cmd = "dAmnServer"; mCompatibilityMode = true; }
            if (!mCompatibilityMode)
            {
                if (p.args.ContainsKey("compression"))
                {
                    if (p.args["compression"].ToLower().Trim() == "deflate" ||
                        p.args["compression"].ToLower().Trim() == "enable")
                        this.CompressionEnabled = true;
                    else if (p.args["compression"].ToLower().Trim() == "none" ||
                            p.args["compression"].ToLower().Trim() == "disable")
                    {
                        this.CompressionEnabled = false;
                    }
                    else
                    {
                        Disconnect(string.Format("invalid compression mode {0}", p.args["compression"].ToLower().Trim()));
                        return;
                    }
                }
                toClient.args["compression"] = this.CompressionEnabled ? "deflate" : "none";
            }
            toClient.param = p.param; //Wrong, Send them what they sent us.
            this.State = ConnectionState.STATE_WAITINGFORAUTH;
            SendPacket(toClient);
        }
        bool mCompatibilityMode = true;
        [PacketHandler("kill")]
        [PacketHandler("disconnect")]
        [PacketHandler("reload")]
        protected void OnNormalBEPacket(Packet p, IConnection sender)
        {
            if (mCurrentUser == null)
            {
                Disconnect("bad msg");
                return;
            }
           Backend.Implementation.HandlePacket(p, sender);
        }
        [PacketHandler("login")]
        protected void OnLoginPacket(Packet p, IConnection sender)
        {
            if (this.mCurrentUser != null)
            {
                Disconnect("bad msg");
                return;
            }
            Backend.Implementation.HandlePacket(p, sender);
        }
    }
}
